#include <QDockWidget>
#include <QFileDialog>
#include <QMessageBox>

#include "datamanagerview.h"
#include "../mainwindow.h"
#include "../renderer/rendermanager.h"
#include "geometryattribewidget.h"
#include "../data/fileplugin.h"
#include "renamedialog.h"

using namespace PBVP;

DataManagerView::DataManagerView(MainInterface *pMainInterface, QWidget *parent)
: QListWidget(parent)
{
	m_pDataManager = pMainInterface->getDataManager();
	m_pFileExtensionManager = pMainInterface->getFileExtensionManager();
	m_pMainWindow = pMainInterface->getMainWindow();
	propDock = m_pMainWindow->propDock;

	for(int i = 0; i < m_pDataManager->numOfDataSets(); i++) {
		DataNode *pData = m_pDataManager->dataNodeAt(i);
		addItem(pData->getName());
	}
	// connect(m_pDataManager, SIGNAL(datasetChanged()), this, SLOT(updateAll()));
	connect(m_pDataManager, SIGNAL(datasetAdded()), this, SLOT(updateAll()));
	connect(m_pDataManager, SIGNAL(datasetDeleted()), this, SLOT(updateAll()));
	connect(m_pDataManager, SIGNAL(datasetDeleted()), this, SLOT(hidePropertyPane()));
	connect(this, SIGNAL(datanodeChanged()), this, SLOT(updateAll()));

	popupMenu = new QMenu(this);

	connect(this, SIGNAL(itemRightClicked(QListWidgetItem*, const QPoint&)), 
		this, SLOT(showPopupMenu(QListWidgetItem*, const QPoint&)));

	connect(this, SIGNAL(currentRowChanged(int)), this, SLOT(dataClicked(int)));
	connect(this, SIGNAL(currentRowChanged(int)), m_pDataManager, SLOT(setCurrentNode(int)));

	showPropertiesAction = new QAction(tr("&Show Properties"), this);
	connect(showPropertiesAction, SIGNAL(triggered()), this, SLOT(showDataProperties()));
	popupMenu->addAction(showPropertiesAction);

	renderSelect = new RenderSelectDialog(this);
	selectRendererAction = new QAction(tr("&Choose Renderer"), this);
	connect(selectRendererAction, SIGNAL(triggered()), this, SLOT(changeRenderer()));
	popupMenu->addAction(selectRendererAction);

	renameAction = new QAction(tr("Rename"), this);
	connect(renameAction, SIGNAL(triggered()), this, SLOT(renameDataNode()));
	popupMenu->addAction(renameAction);

	popupMenu->addSeparator();
	itemDeleteAction = new QAction(tr("&Delete Data"), this);
	connect(itemDeleteAction, SIGNAL(triggered()), this, SLOT(deleteCurrent()));
	popupMenu->addAction(itemDeleteAction);

	dataSaveAction = new QAction(tr("&Save Data"), this);
	connect(dataSaveAction, SIGNAL(triggered()), this, SLOT(saveCurrent()));
	popupMenu->addAction(dataSaveAction);
}

DataManagerView::~DataManagerView()
{
}

void DataManagerView::mousePressEvent(QMouseEvent *e)
{
	QListWidget::mousePressEvent(e);
	if(e->button() == Qt::RightButton) {
		QListWidgetItem *item = currentItem();
		m_Pos = mapToGlobal(e->pos());
		emit itemRightClicked(item, m_Pos);
	}
}

//////////////////////////////////////////////////////////////////////////
// Public slots
//////////////////////////////////////////////////////////////////////////
void DataManagerView::updateAll()
{
	clear();
	for(int i = 0; i < m_pDataManager->numOfDataSets(); i++) {
		DataNode *pData = m_pDataManager->dataNodeAt(i);
		addItem(pData->getName());
	}
}

void DataManagerView::deleteCurrent()
{
	int i = currentRow();
	if (i < 0) return;
	m_pDataManager->deleteDataNode(i);
}

void DataManagerView::saveCurrent()
{
	int i = currentRow();
	if (i < 0) return;
	DataNode *dataNode = m_pDataManager->dataNodeAt(i);
	QString fname = QFileDialog::getSaveFileName(m_pMainWindow, "Save File", "", 
												 m_pFileExtensionManager->filter(dataNode->data()->getDataSetType()));
	if (fname.isNull()) return;
    FilePluginInterface *pFilePlugin = m_pFileExtensionManager->getSupportedPlugin(fname);
	if(!pFilePlugin)
	{
		QString warning = QString("Unknown File Extension: ").append(fname);
		QMessageBox::warning(m_pMainWindow, "Save Failed", warning);
		return;
	}
	if(!pFilePlugin->saveFile(dataNode->data(), fname)) {
		QMessageBox::warning(m_pMainWindow, "Warning", "File Save Failed");
	}
}

void DataManagerView::showPopupMenu(QListWidgetItem *item, const QPoint& pos)
{
	popupMenu->popup(pos);
}

void DataManagerView::showDataProperties()
{
	int i = currentRow();
	if (i < 0) return;

	DataNode *dataNode = m_pDataManager->dataNodeAt(i);
	QWidget *attribWidget = dataNode->getPropertyWidget();
	if(attribWidget) {
		QWidget *prev = propDock->widget();
		if(prev) prev->hide();
		attribWidget->setParent(propDock);
		propDock->setWidget(attribWidget);
		attribWidget->show();
	}
	propDock->show();
}

void DataManagerView::changeRenderer()
{
	RenderManager *pRenderManager = m_pMainWindow->getRenderManager();
	int i = currentRow();
	if(i < 0) return;
	DataNode *pCurNode = m_pDataManager->dataNodeAt(i);
	QList<RenderPlugin *> renderList = pRenderManager->getSupportedPlugins(pCurNode->data());

	renderSelect->setRenderList(renderList);
	if(renderSelect->exec()) {
		i = renderSelect->selectedId();
		if (i >= 0)
		{
			pCurNode->setRenderer(renderList[i]->clone());
			emit rendererChanged();
		}
	}
}

void DataManagerView::renameDataNode()
{
	int i = currentRow();
	if(i < 0) return;
	DataNode *dataNode = m_pDataManager->dataNodeAt(i);

	RenameDialog renameDialog(dataNode->getName(), m_pMainWindow);
	if(renameDialog.exec()) {
		QString newName = renameDialog.getNewName();
		dataNode->setName(newName);
	}
	emit datanodeChanged();
}

void DataManagerView::dataClicked(int i)
{
	if(i < 0) {
		return;
	}
	if(!propDock->isVisible()) return;
	QWidget *attribWidget = m_pDataManager->dataNodeAt(i)->getPropertyWidget();
	if(attribWidget) {
		QWidget *prev = propDock->widget();
		if(prev) prev->hide();
		attribWidget->setParent(propDock);
		propDock->setWidget(attribWidget);
		attribWidget->show();
	}
}

void DataManagerView::hidePropertyPane()
{
	propDock->hide();
}
